// CSE-102 DSA Assignment - Implementation of the python's list functions in C (Array Implementation).
// Ankit Mittal - 2010015


#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<string.h>

int in=0;					// 'in' represents the highest index in the list. 
int *arr;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void inputlist()
{	int x=99;
	char terminator='a';
	printf("Enter the list elements seperated by a comma without using any white spaces: ");
	while(terminator!='\n')
	{	arr=realloc(arr,(in+1)*sizeof(int));
		scanf("%d",&x);
		scanf("%c",&terminator);		
		arr[in++]=x;
	}
	in--;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void printlist()
{	int i=0;
	printf("\nRequired List: [");
	printf("%d",arr[i++]);
	while(i<=in)
	{	printf(", %d",arr[i++]);
	}
	printf("]\n");
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void transversing()
{	int i;
	printf("\nEnter the index of the element to be printed: ");
	scanf("\n%d",&i);
	if(i<0)
	{	i=in+i+1;
	}
	if(i<0||i>in)
	{	printf("\nNo such index...");
		return;
	}
	printf("\nThe required element is: %d",arr[i]);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void slicing()
{	int i,n1,n2;
	printf("\nEnter the slice indeces seperated by a colon: ");
	scanf("\n%d:%d",&n1,&n2);
	if(n1<0)
		n1=in+n1+1;
	if(n2<0)
		n2=in+n2+1;
	if(n1>=n2||n1>in)
	{	printf("\nSliced portion of the List: []\n");
		return;
	}
	printf("\nSliced portion of the List: [");
	i=n1;
	printf("%d",arr[i++]);
	while(i<n2&&i<=in)
	{	printf(", %d",arr[i++]);
	}
	printf("]\n");
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void reverse()
{	int fwd, bck, temp;
	for(fwd=0,bck=in;fwd<=in/2;fwd++,bck--)
	{	temp=arr[fwd];
		arr[fwd]=arr[bck];
		arr[bck]=temp;
	}
	printlist();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void append()
{	int ele;
	printf("\nEnter the element to be inserted: ");
	scanf("\n%d",&ele);
	arr=realloc(arr,(in+2)*sizeof(int));
	arr[++in]=ele;
	printlist();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void sort()
{	int i, j, temp;
	for(i=0;i<in;i++)
	{	for(j=0;j<in-i;j++)
		{	if(arr[j]>arr[j+1])
			{	temp=arr[j];
				arr[j]=arr[j+1];
				arr[j+1]=temp;
			}
		}
	}
	printlist();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void removing()
{	int ele, i;
	printf("\nEnter the element whose first occurence has to be removed: ");
	scanf("\n%d",&ele);
	for(i=0;i<=in;i++)
	{	if(arr[i]==ele)
		break;
	}
	if(i==in+1)
	{	printf("\nElement not found...\n");
		return;
	}
	if(in==0)
	{	printf("\nRequired List: []\n");
		in=-1;
		return;
	}
	else
	{	for(i=i;i<in;i++)
		{	arr[i]=arr[i+1];
		}
		arr=realloc(arr,(in)*sizeof(int));
		in--;
	}	
	printlist();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void count()
{	int ele, i;
	int cnt=0;
	printf("\nEnter the element whose number of occurences you want to count: ");
	scanf("\n%d",&ele);
	for(i=0;i<=in;i++)
		{	if(arr[i]==ele)
				cnt+=1;
		}
	printf("\n%d appears %d times in the list.",ele,cnt);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void indexing()
{	int ele;
	int i;
	printf("\nEnter the element, the index of whose first occurence has to be returned: ");
	scanf("\n%d",&ele);
	for(i=0;i<=in;i++)
	{	if(arr[i]==ele)
		{	printf("\nElement %d first occurs at index %d",ele,i);
			break;
		}
	}
	if(i==in+1)
	{	printf("\nNo such element...\n");	
	}
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void insert()
{	int ele, i;
	int pos;
	printf("\nEnter the insertion index(i) and the value to be inserted(x) in the i,x format: ");
	scanf("\n%d,%d",&pos,&ele);
	if(pos<0)
	{	pos=in+pos+2;
	}
	if(pos>in+1||pos<0)
	{	printf("\nIndex not reachable...\n");
	}
	else
	{	arr=realloc(arr,(in+2)*sizeof(int));
		arr[in+1]=0;
		for(i=in+1;i>pos;i--)
		{	arr[i]=arr[i-1];
		}
		arr[pos]=ele;
		in++;
		printlist();
	}
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void extend()
{	int x;
	char terminator='a';
	printf("\nEnter the list elements seperated by a comma without asing any white spaces: ");
	while(terminator!='\n')
	{	arr=realloc(arr,(in+2)*sizeof(int));
		scanf("%d",&x);
		scanf("%c",&terminator);		
		arr[++in]=x;
	}
	printlist();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void poping()
{	int ele, i;
	printf("\nEnter the index of the element to be deleted: ");
	scanf("\n%d",&i);
	if(i<0)
	{	i=in+i+1;
	}
	if(i<0||i>in)
	{	printf("\nIndex not reachable...\n");
		return;
	}
	if(in==0)
	{	printf("\nRequired List: []\n");
		in=-1;
		return;
	}
	else
	{	for(i=i;i<in;i++)
		{	arr[i]=arr[i+1];
		}
		arr=realloc(arr,(in)*sizeof(int));
		in--;
	}
	printlist();	
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void length()
{	printf("\nThe length of the list is: %d.",in+1);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
int main()
{	char op;
	char more;
	inputlist();
	printlist();
	do
	{	printf("\nR-Reversal\tI-Indexing\tL-Length\tS-Slicing");
		printf("\nQ-Sorting\tX-Removing\tJ-Insert\tP-Pop");
		printf("\nA-Append\tE-Extend\tT-Transversing");
		printf("\nC-Count\t\tD-Display");
		printf("\n\nEnter the list operation: ");
		scanf("\n%c",&op);
		switch(op)
		{	case('T'):  transversing();
  						break;
			case('S'):  slicing();
						break;
			case('R'):  reverse();
						break;
			case('A'):  append();
						break;
			case('Q'):  sort();
						break;
			case('X'):  removing();
						break;
			case('C'):  count();
						break;
			case('I'):  indexing();
						break;
			case('J'):  insert();
						break;
			case('E'):  extend();
						break;
			case('P'):  poping();
						break;
			case('L'):  length();
						break;
			case('D'):  printlist();
						break;
			case('t'):  transversing();
  						break;
			case('s'):  slicing();
						break;
			case('r'):  reverse();
						break;
			case('a'):  append();
						break;
			case('q'):  sort();
						break;
			case('x'):  removing();
						break;
			case('c'):  count();
						break;
			case('i'):  indexing();
						break;
			case('j'):  insert();
						break;
			case('e'):  extend();
						break;
			case('p'):  poping();
						break;
			case('l'):  length();
						break;
			case('d'):  printlist();
						break;
		}
		printf("\nMore operations?(y/n): ");
		scanf("\n%c",&more);
	}while(more=='y'||more=='Y');
	getchar();
	return 0;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
